package com.gbase8c.dmt.db.opengauss;

import com.gbase8c.dmt.db.object.RoleObject;

import com.gbase8c.dmt.model.migration.dto.DataSourceDto;
import com.gbase8c.dmt.model.migration.dto.RoleDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.dbutils.*;
import org.apache.commons.dbutils.handlers.ColumnListHandler;

import java.util.List;
import java.util.Map;

@Slf4j
public class RoleObjectImpl extends MetaImpl implements RoleObject {

    public RoleObjectImpl(DataSourceDto dataSourceDto) {
        super(dataSourceDto);
    }

    @Override
    public List<String> getNames(Map<String, Object> params) {
        return null;
    }

    @Override
    public RoleDto get(String name, Map<String, Object> params) {
        return null;
    }

    @Override
    public RoleDto convert(RoleDto roleDto, Map<String, Object> params) {
        if (roleDto != null){
            //迁移状态置为是
            roleDto.setConvertible(Boolean.TRUE);
        } else {
            roleDto.setConvertible(Boolean.FALSE);
        }

        if (roleDto.getConvertible()){
            roleDto.setConvertMsg("已完成");
        }else {
            roleDto.setConvertMsg("失败");
        }

        return roleDto;
    }

    @Override
    public String sql(RoleDto roleDto, Map<String, Object> params) {
        //角色权限如果角色名是Mysql中的"root"，不建立root用户，把其权限都加到gbase用户
        String existRolesql = "SELECT rolname from pg_roles;";
        BeanProcessor beanProcessor = new GenerousBeanProcessor();
        RowProcessor rowProcessor = new BasicRowProcessor(beanProcessor);

        boolean preserveCase = roleDto.getTask().getMigrateConfig().isPreserveCase();

        List<String> existRole = null;
        existRole = query(existRolesql, new ColumnListHandler<String>());

        StringBuilder sb = new StringBuilder();
        if (!existRole.contains(roleDto.getName().toLowerCase()) && ! roleDto.getName().toLowerCase().equals("root")){
            String roleName = roleDto.getName().toLowerCase();
            sb.append("CREATE ROLE ").append(roleName)
                    .append(" with password \'gbase;123\'")
                    .append(";").append("\r\n");
        }

        //建系统权限
        RoleDto.SysPrivDto sysPrivDto = roleDto.getSysPrivDto();
        //将对应权限处理成List格式，因为系统权限要逐个执行语句
        List<String> sysprivs = sysPrivilege2String(null,sysPrivDto);
        if (!sysprivs.equals("") && sysprivs != null){
            if (roleDto.getName().equals("root")){

            }else {
                for (String syspriv:sysprivs){
                    sb.append("Alter role " + roleDto.getName().toLowerCase() + " with " + syspriv + ";");
                }
            }
        }

        //建库级权限
        if (roleDto.getDatabasePrivDtos() != null){
            List<RoleDto.DatabasePrivDto> databasePrivDtos = roleDto.getDatabasePrivDtos();
            for (RoleDto.DatabasePrivDto databasePrivDto:databasePrivDtos){
                if (databasePrivDto.getCreatePriv().equals("Y")){
                    //grant create on schema gaitest to role01;
                    sb.append("GRANT CREATE ON SCHEMA " + wrap(databasePrivDto.getSchemaName(), preserveCase)+" to " + roleDto.getName()+";").append("\r\n");
                }
                //将对应权限处理成一个字符串，可一个语句赋予多个权限
                String databaseprivs = databasePrivilege2String(null,databasePrivDto);
                if (!sysprivs.equals("") && sysprivs != null){
                    if (roleDto.getName().equals("root")){
                        //grant select,insert on all tables in SCHEMA gaitest to user01;
                        //把第一个逗号去掉
                        sb.append("GRANT " + databaseprivs.substring(1,databaseprivs.length()-1) + " on all tables in schema "
                                + wrap(databasePrivDto.getSchemaName(), preserveCase) + " to " + "gbase" + " ;");
                    }else {
                        //grant select,insert on all tables in SCHEMA gaitest to user01;
                        //把第一个逗号去掉
                        sb.append("GRANT " + databaseprivs.substring(1,databaseprivs.length()-1) + " on all tables in schema "
                                + wrap(databasePrivDto.getSchemaName(), preserveCase) + " to " + roleDto.getName() + ";");
                    }
                }
            }
        }

        //建表级权限
        if (roleDto.getTablePrivDtos() != null){
            List<RoleDto.TablePrivDto> tablePrivDtos = roleDto.getTablePrivDtos();
            for (RoleDto.TablePrivDto tablePrivDto:tablePrivDtos){
                //将对应权限处理成一个字符串，可一个语句赋予多个表级权限
                String tableprivs = tablePrivilege2String(null,tablePrivDto);
                if (!tableprivs.equals("") && tableprivs != null){
                    if (roleDto.getName().equals("root")){
                        //grant select,insert on gaitest.t_student to user01;
                        //把第一个逗号去掉
                        sb.append("GRANT " + tableprivs.substring(1,tableprivs.length()-1) + " on "
                                + wrap(tablePrivDto.getSchemaName(), preserveCase) + "."+tablePrivDto.getTableName() +" to " + "gbase" + " ;");
                    }else {
                        //grant select,insert on gaitest.t_student to user01;
                        //把第一个逗号去掉
                        sb.append("GRANT " + tableprivs.substring(1,tableprivs.length()-1) + " on "
                                + wrap(tablePrivDto.getSchemaName(), preserveCase) + "."+tablePrivDto.getTableName() +" to " + roleDto.getName() + " ;");
                    }
                }
            }
        }

        //建列级权限
        if (roleDto.getColumnPrivDtos() != null){
            List<RoleDto.ColumnPrivDto> columnPrivDtos = roleDto.getColumnPrivDtos();
            for (RoleDto.ColumnPrivDto columnPrivDto:columnPrivDtos){
                //将对应权限处理成一个字符串，可一个语句赋予多个列级权限
                String columnprivs = columnPrivilege2String(null,columnPrivDto);
                if (!columnprivs.equals("") && columnprivs != null){
                    if (roleDto.getName().equals("root")){
                        //grant insert,select(name) on gaitest.t_student to user01;
                        //把第一个逗号去掉
                        sb.append("GRANT " + columnprivs.substring(1,columnprivs.length()-1) + "("+ columnPrivDto.getColumnName()+") on "
                                + wrap(columnPrivDto.getSchemaName(), preserveCase) + "."+ columnPrivDto.getTableName() +" to " + "gbase" + " ;");
                    }else {
                        //grant insert,select(name) on gaitest.t_student to user01;
                        //把第一个逗号去掉
                        sb.append("GRANT " + columnprivs.substring(1,columnprivs.length()-1) + "("+ columnPrivDto.getColumnName()+") on "
                                + wrap(columnPrivDto.getSchemaName(), preserveCase) + "."+ columnPrivDto.getTableName() +" to " + roleDto.getName() + " ;");
                    }
                }
            }
        }
        log.info(String.valueOf(sb).toLowerCase());
        return sb.toString().toLowerCase();
    }
}
